/**
 * 跨平台音频播放器工具类
 * 支持H5、小程序、App等不同环境的音频播放
 */

/**
 * 音频播放器类
 */
export class AudioPlayer {
    constructor() {
        this.audioContext = null;
        this.currentAudio = null;
        this.isPlaying = false;
        this.isLoading = false;
        this.currentTime = 0;
        this.duration = 0;
        
        // 进度更新定时器
        this.progressTimer = null;
        
        // 事件监听器
        this.onPlayCallback = null;
        this.onPauseCallback = null;
        this.onEndedCallback = null;
        this.onErrorCallback = null;
        this.onTimeUpdateCallback = null;
        this.onLoadedCallback = null;
    }

    /**
     * 加载音频
     * @param {Object} audio 音频对象
     * @param {String} audio.file_path 音频文件路径
     * @param {String} audio.name 音频文件名
     * @param {Number} audio.duration 音频时长
     */
    async loadAudio(audio) {
        return new Promise((resolve) => {
            try {
                // 检查是否重复加载同一音频
                if (this.currentAudio && 
                    this.currentAudio.id === audio.id && 
                    this.currentAudio.file_path === audio.file_path && 
                    this.audioContext && 
                    !this.isLoading) {
                    console.log('音频已加载，无需重复加载:', audio.name);
                    resolve(true);
                    return;
                }
                
                // 如果正在加载其他音频，先取消
                if (this.isLoading) {
                    console.warn('正在加载其他音频，取消当前加载');
                    this.destroy();
                }
                
                // 验证音频URL
                if (!validateAudioUrl(audio.file_path)) {
                    this.triggerError('无效的音频文件路径');
                    resolve(false);
                    return;
                }
                
                // 销毁之前的音频上下文
                if (this.currentAudio && this.currentAudio.id !== audio.id) {
                    this.destroy();
                }
                
                this.currentAudio = audio;
                this.isLoading = true;
                
                // #ifdef H5
                // H5环境使用HTML5 Audio API
                this.audioContext = new Audio();
                this.audioContext.crossOrigin = 'anonymous'; // 解决跨域问题
                this.audioContext.preload = 'metadata';
                
                // 设置H5事件监听
                this.setupH5Listeners();
                
                // 等待音频元数据加载完成
                const onLoadedMetadata = () => {
                    this.isLoading = false;
                    this.duration = this.audioContext.duration || 0;
                    console.log('音频已加载:', audio.name, '时长:', this.duration);
                    this.triggerLoaded();
                    resolve(true);
                };
                
                const onLoadError = (e) => {
                    this.isLoading = false;
                    console.error('音频加载失败:', e);
                    this.triggerError('音频加载失败: ' + (e.message || 'The element has no supported sources'));
                    resolve(false);
                };
                
                // 添加一次性事件监听
                this.audioContext.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
                this.audioContext.addEventListener('error', onLoadError, { once: true });
                
                // 设置超时处理
                setTimeout(() => {
                    if (this.isLoading) {
                        this.isLoading = false;
                        console.warn('音频加载超时');
                        this.triggerError('音频加载超时，请检查网络连接');
                        resolve(false);
                    }
                }, 10000); // 10秒超时
                
                // 最后设置src，触发加载
                this.audioContext.src = audio.file_path;
                // #endif
                
                // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
                // 小程序和App环境使用uni.createInnerAudioContext
                this.audioContext = uni.createInnerAudioContext();
                this.audioContext.src = audio.file_path;
                
                // 设置uni-app事件监听
                this.setupUniAppListeners();
                
                // uni-app环境下直接返回成功
                this.isLoading = false;
                console.log('音频已加载:', audio.name);
                resolve(true);
                // #endif
                
            } catch (error) {
                this.isLoading = false;
                console.error('加载音频失败:', error);
                this.triggerError('加载音频失败: ' + error.message);
                resolve(false);
            }
        });
    }

    /**
     * 播放音频
     */
    async play() {
        if (!this.audioContext) {
            this.triggerError('音频上下文未初始化');
            return false;
        }

        if (this.isLoading) {
            this.triggerError('音频正在加载中，请稍候');
            return false;
        }

        try {
            // #ifdef H5
            // H5环境下等待音频可以播放
            if (this.audioContext.readyState < 3) { // HAVE_FUTURE_DATA
                await new Promise((resolve, reject) => {
                    const onCanPlay = () => {
                        this.audioContext.removeEventListener('canplay', onCanPlay);
                        this.audioContext.removeEventListener('error', onError);
                        resolve();
                    };
                    const onError = (e) => {
                        this.audioContext.removeEventListener('canplay', onCanPlay);
                        this.audioContext.removeEventListener('error', onError);
                        reject(e);
                    };
                    this.audioContext.addEventListener('canplay', onCanPlay, { once: true });
                    this.audioContext.addEventListener('error', onError, { once: true });
                    
                    // 设置超时
                    setTimeout(() => {
                        this.audioContext.removeEventListener('canplay', onCanPlay);
                        this.audioContext.removeEventListener('error', onError);
                        reject(new Error('音频准备超时'));
                    }, 3000);
                });
            }
            // #endif
            
            await this.audioContext.play();
            this.isPlaying = true;
            this.startProgressTimer(); // 启动进度定时器
            console.log('开始播放音频:', this.currentAudio?.name);
            return true;
        } catch (error) {
            console.error('播放音频失败:', error);
            this.triggerError('播放失败: ' + error.message);
            return false;
        }
    }

    /**
     * 暂停音频
     */
    pause() {
        if (!this.audioContext) {
            this.triggerError('音频上下文未初始化');
            return false;
        }

        try {
            this.audioContext.pause();
            this.isPlaying = false;
            this.stopProgressTimer(); // 停止进度定时器
            console.log('暂停播放音频');
            return true;
        } catch (error) {
            console.error('暂停音频失败:', error);
            this.triggerError('暂停失败: ' + error.message);
            return false;
        }
    }

    /**
     * 停止音频
     */
    stop() {
        if (!this.audioContext) {
            return true;
        }

        try {
            // #ifdef H5
            this.audioContext.pause();
            this.audioContext.currentTime = 0;
            // #endif
            
            // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
            this.audioContext.stop();
            // #endif
            
            this.isPlaying = false;
            this.currentTime = 0;
            this.stopProgressTimer(); // 停止进度定时器
            console.log('停止播放音频');
            return true;
        } catch (error) {
            console.error('停止音频失败:', error);
            return false;
        }
    }

    /**
     * 设置播放进度
     * @param {Number} time 时间（秒）
     */
    setCurrentTime(time) {
        if (!this.audioContext) return false;

        try {
            // #ifdef H5
            this.audioContext.currentTime = time;
            // #endif
            
            // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
            this.audioContext.seek(time);
            // #endif
            
            this.currentTime = time;
            return true;
        } catch (error) {
            console.error('设置播放进度失败:', error);
            return false;
        }
    }

    /**
     * 设置音量
     * @param {Number} volume 音量值，范围 0-1
     */
    setVolume(volume) {
        if (!this.audioContext) return false;

        try {
            // 确保音量值在有效范围内
            const validVolume = Math.max(0, Math.min(1, volume));
            
            // #ifdef H5
            this.audioContext.volume = validVolume;
            // #endif
            
            // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
            this.audioContext.volume = validVolume;
            // #endif
            
            console.log('音量设置成功:', validVolume);
            return true;
        } catch (error) {
            console.error('设置音量失败:', error);
            return false;
        }
    }

    /**
     * 启动进度更新定时器
     */
    startProgressTimer() {
        // 先停止之前的定时器
        this.stopProgressTimer();
        
        // 每300ms更新一次进度
        this.progressTimer = setInterval(() => {
            if (this.isPlaying && this.audioContext) {
                try {
                    // #ifdef H5
                    this.currentTime = this.audioContext.currentTime || 0;
                    // #endif
                    
                    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
                    this.currentTime = this.audioContext.currentTime || 0;
                    // #endif
                    
                    this.triggerTimeUpdate();
                } catch (error) {
                    console.error('获取播放时间失败:', error);
                }
            }
        }, 300);
        
        console.log('启动进度更新定时器');
    }
    
    /**
     * 停止进度更新定时器
     */
    stopProgressTimer() {
        if (this.progressTimer) {
            clearInterval(this.progressTimer);
            this.progressTimer = null;
            console.log('停止进度更新定时器');
        }
    }

    /**
     * 销毁音频上下文
     */
    destroy() {
        if (this.audioContext) {
            try {
                this.stop();
                this.stopProgressTimer(); // 停止进度定时器
                
                // #ifdef H5
                this.audioContext.src = '';
                this.audioContext = null;
                // #endif
                
                // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
                this.audioContext.destroy();
                this.audioContext = null;
                // #endif
                
            } catch (error) {
                console.warn('销毁音频上下文时出错:', error);
            }
        }
        
        this.currentAudio = null;
        this.isPlaying = false;
        this.isLoading = false;
        this.currentTime = 0;
        this.duration = 0;
    }

    /**
     * 设置H5环境的事件监听
     */
    setupH5Listeners() {
        // #ifdef H5
        if (!this.audioContext) return;

        this.audioContext.addEventListener('loadedmetadata', () => {
            this.duration = this.audioContext.duration || 0;
            this.triggerLoaded();
        });

        this.audioContext.addEventListener('play', () => {
            this.isPlaying = true;
            this.triggerPlay();
        });

        this.audioContext.addEventListener('pause', () => {
            this.isPlaying = false;
            this.triggerPause();
        });

        this.audioContext.addEventListener('ended', () => {
            this.isPlaying = false;
            this.currentTime = 0;
            this.triggerEnded();
        });

        this.audioContext.addEventListener('error', (e) => {
            this.isPlaying = false;
            this.triggerError('音频播放错误: ' + (e.message || '未知错误'));
        });

        this.audioContext.addEventListener('timeupdate', () => {
            this.currentTime = this.audioContext.currentTime || 0;
            this.triggerTimeUpdate();
        });
        // #endif
    }

    /**
     * 设置uni-app环境的事件监听
     */
    setupUniAppListeners() {
        // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || APP-PLUS
        if (!this.audioContext) return;

        this.audioContext.onCanplay(() => {
            this.duration = this.audioContext.duration || 0;
            this.triggerLoaded();
        });

        this.audioContext.onPlay(() => {
            this.isPlaying = true;
            this.triggerPlay();
        });

        this.audioContext.onPause(() => {
            this.isPlaying = false;
            this.triggerPause();
        });

        this.audioContext.onEnded(() => {
            this.isPlaying = false;
            this.currentTime = 0;
            this.triggerEnded();
        });

        this.audioContext.onError((err) => {
            this.isPlaying = false;
            this.triggerError('音频播放错误: ' + JSON.stringify(err));
        });

        this.audioContext.onTimeUpdate(() => {
            this.currentTime = this.audioContext.currentTime || 0;
            this.triggerTimeUpdate();
        });
        // #endif
    }

    /**
     * 事件监听器设置方法
     */
    onPlay(callback) { this.onPlayCallback = callback; }
    onPause(callback) { this.onPauseCallback = callback; }
    onEnded(callback) { this.onEndedCallback = callback; }
    onError(callback) { this.onErrorCallback = callback; }
    onTimeUpdate(callback) { this.onTimeUpdateCallback = callback; }
    onLoaded(callback) { this.onLoadedCallback = callback; }

    /**
     * 事件触发方法
     */
    triggerPlay() { if (this.onPlayCallback) this.onPlayCallback(); }
    triggerPause() { if (this.onPauseCallback) this.onPauseCallback(); }
    triggerEnded() { if (this.onEndedCallback) this.onEndedCallback(); }
    triggerError(error) { if (this.onErrorCallback) this.onErrorCallback(error); }
    triggerTimeUpdate() { if (this.onTimeUpdateCallback) this.onTimeUpdateCallback(this.currentTime, this.duration); }
    triggerLoaded() { if (this.onLoadedCallback) this.onLoadedCallback(this.duration); }
}

/**
 * 格式化时间显示
 * @param {Number} seconds 秒数
 * @returns {String} 格式化的时间字符串
 */
export const formatPlayTime = (seconds) => {
    if (!seconds || seconds < 0) return '0:00';
    
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    
    return `${mins}:${secs.toString().padStart(2, '0')}`;
};

/**
 * 验证音频文件URL是否有效
 * @param {String} url 音频文件URL
 * @returns {Boolean} 是否有效
 */
export const validateAudioUrl = (url) => {
    if (!url || typeof url !== 'string') {
        console.warn('音频URL为空或格式错误:', url);
        return false;
    }
    
    // 移除空白字符
    url = url.trim();
    if (!url) {
        console.warn('音频URL为空字符串');
        return false;
    }
    
    // 检查URL格式 - 支持绝对路径、相对路径和完整URL
    const urlPattern = /^(https?:\/\/[^\s]+)|(\/[^\s]*)|(\.\.?\/[^\s]*)|([a-zA-Z]:\\[^\s]*)|([^\s]+\.[a-zA-Z0-9]+)$/;
    if (!urlPattern.test(url)) {
        console.warn('音频URL格式不正确:', url);
        return false;
    }
    
    // 检查音频文件扩展名，支持更多格式
    const audioExtensions = /\.(mp3|wav|m4a|aac|ogg|flac|wma|opus)(\?[^\s]*)?$/i;
    if (!audioExtensions.test(url)) {
        console.warn('不支持的音频文件格式:', url);
        return false;
    }
    
    // 检查URL长度（防止过长的URL）
    if (url.length > 2048) {
        console.warn('音频URL过长:', url.length);
        return false;
    }
    
    console.log('音频URL验证通过:', url);
    return true;
};

// 创建单例音频播放器实例
export const globalAudioPlayer = new AudioPlayer();
